/**************************************************************************
 * @doc CONFIGURATION
 * @module ztconf.c |
 * Source code for Loading the SoftPay Assist Zontalk configuration parameters
 * into the data files.
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :
 * <nl>Notes       :
 *
 * @head3 Zontalk configuration Functions |
 * @index | index_name
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
$Log:  $
 * ------------------------------------------------------------------------
 ********************************************************************************/

#include <project.h>                // MUST BE FIRST FILE INCLUDED

#define VSZTCONF_C

#include <aclconio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <acdce.h>
#include <errno.h>
#include <applidl.h>

/** /#define DEBUG_VSZTCONF*/
#ifdef DEBUG_VSZTCONF
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <scalls.h>
#include <ztconf.h>
#include <spdebug.h>
#include <confio.h>
#include <aat.h>
#include <cdt.h>
#include <hdt.h>
#include <tblutil.h>
#include <ict.h>
#include <lct.h>
#include <pct.h>
#include <tct.h>
#include <bdt.h>
#include <sdt.h>
#include <cst.h>
#include <cct.h>
#include <crt.h>
#include <dct.h>
#include <dpt.h>
#include <sct.h>
#include <udt.h>
#include <iit.h>
#include <pit.h>
#include <trt.h>
#include <msg.h>
#include <msgfuncs.h>
#include <spamsg.h>
#include <ui.h>
#include <menufunc.h>
#include <modem.h>
#include <file.h>
#include <mem.h>
#include <mit.h>
#include <mht.h>
#ifdef VXEMVAPP
#include <emvsizes.h>
#include <mvt.h>
#endif

char* aszParamNames[] = {
    "AAT",
    "BDT",
    #ifdef CHECK_DEFINED
    "CCT",
    #endif
    "CDT",
    #ifdef MODEM
    "CPT",
    #endif
    #ifdef CR600_DEFINED
    "CRT",
    #endif
    "CST",
    "DCT",
    "HDT",
    #ifdef ISDN_DEFINED
    "ICT",
    #endif
    "IIT",
    "LCT",
    "MHT",
    "MIT",
    #ifdef EMV_MODULE
    "MVT",
    #endif
#ifdef VXEMVAPP
    "MVT",
#endif
    "PCT",
    "PIT",
    "SCT",
    #ifdef SHIFT_DEFINED
    "SDT",
    #endif
    "TCT",
    #ifdef CLERK_DEFINED
    "UDT",
    #endif
    "\0"
};


int ainRecordSizes[] = {
    SIZE_AAT_REC,
    SIZE_BDT_REC,
    #ifdef CHECK_DEFINED
    SIZE_CCT_REC,
    #endif
    SIZE_CDT_REC,
    #ifdef MODEM
    SIZE_CPT_REC,
    #endif
    #ifdef CR600_DEFINED
    SIZE_CRT_REC,
    #endif
    SIZE_CST_REC,
    SIZE_DCT_REC,
    SIZE_HDT_REC,
    #ifdef ISDN_DEFINED
    SIZE_ICT_REC,
    #endif
    SIZE_IIT_REC,
    SIZE_LCT_REC,
    SIZE_MHT_REC,
    SIZE_MIT_REC,
    #ifdef EMV_MODULE
    SIZE_MVT_REC,
    #endif
#ifdef VXEMVAPP
    SIZE_MVT_REC,
#endif
    SIZE_PCT_REC,
    SIZE_PIT_REC,
    SIZE_SCT_REC,
    #ifdef SHIFT_DEFINED
    SIZE_SDT_REC,
    #endif
    SIZE_TCT_REC,
    #ifdef CLERK_DEFINED
    SIZE_UDT_REC,
    #endif

    0
};



/* KV1 NOTE:  This needs to be set to the largest configuration structure size */
#define MAX_CONFIG_REC_SIZE         (SIZE_PCT_REC + GEN_VER_SIZE + 1)

VS_BOOL fZtConfigReqd() {
    unsigned char   chZtConfig = 0;
    VS_BOOL fRetVal = VS_TRUE;

    /*
    * if #CZ exists check for the value. If it is 1, it means
    * configuration is required.
    */
    /** /pdebug(("--fZtConfigReqd--"));*/

    if (get_env("#CZ", (char *) &chZtConfig, 1) != 1 || chZtConfig != '1')
        fRetVal = VS_FALSE;

    return(fRetVal);
}

/*********************************************************************************************
* @func VB_BOOL | fZtExprConfReqd |
*      Checks the config.sys variable #CZE
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fZtExprConfReqd() {
    unsigned char   chZtConfig = 0;
    VS_BOOL fRetVal = VS_TRUE;

    /*
    * if #CZE exists check for the value. If it is 1, it means
    * express configuration is required.
    */
    /** /pdebug(("--fZtExprConfReqd--"));*/

    if (get_env("#CZE", (char *) &chZtConfig, 1) != 1 || chZtConfig != '1')
        fRetVal = VS_FALSE;

    return(fRetVal);
}

/*********************************************************************************************
* @func VB_BOOL | fResetZtConfigFlag |
*      Resets the config.sys variable #CZE
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fResetZtConfigFlag() {
    VS_BOOL fRetVal = VS_TRUE;

    /*
    * Remove #CZ from config.sys file.
    */
    /** /pdebug(("--fResetZtConfigFlag--"));*/

    if (put_env("#CZ", "", 0) != VS_SUCCESS)
        fRetVal = VS_FALSE;

    return(fRetVal);
}

/*********************************************************************************************
* @func int | inConvFlds |
*       Converts the config.sys values from strings to actual types
*
* @parm char * | szVarName |
*       Variable Name
*
* @parm char * | szToBuf |
*       Converted value
*
* @parm char * | szFromBuf |
*       Original string value
*
* @parm FieldDefinition * | psrFldAttrList |
*       Field Definition
*
* @parm int | inFldIdx |
*       Field Index
*
* @parm int | inFldSz |
*       Field Size
*
* @parm VB_BOOL | fNewFile |
*       Flag to idnetify new data file
*
* @rdesc return values.
* @flag int    |  Converted Field size
* @end
**********************************************************************************************/

int inConvFlds(char* szVarName,char* szToBuf,char* szFromBuf,FieldDefinition* psrFldAttrList,int inFldIdx,int inFldSz,VS_BOOL fNewFile) {
    char szDispMsg[RESP_MSG_SIZE];
    char szBuf[14 + 1];
    FieldDefinition* psrBitFldAttrList;
    BOOL fOverWrite;
    int inFieldLoc;
    int inFldVal = 0,
    inConvFldSz = 0;
    unsigned long ulFldVal = 0;
    char chBitCount = 0,
    chCurrBit = 0,
    chCurrByte = 0;
    unsigned char   ucConVSyte = 0,
    szTmpBuf[MAX_FIELD_SIZE + 1];
    static unsigned char pucMaskBits[] = {
        0x80,
        0x40,
        0x20,
        0x10,
        0x08,
        0x04,
        0x02,
        0x01
    };
    /** /pdebug(("--inConvFlds--"));*/

    fOverWrite = (unsigned char) (!fNewFile && (psrFldAttrList->fFieldZonTalks == 0) ? VS_FALSE : VS_TRUE);

    switch (psrFldAttrList->ucFieldType) {
    case FLD_BYTE :
        inFldVal = atoi(szFromBuf);
        inConvFldSz = sizeof(char);
        if (fOverWrite)
            memcpy(szToBuf, &inFldVal, inConvFldSz);
        break;

    case FLD_INT :
    case FLD_SHORT:
        inFldVal = atoi(szFromBuf);
        inConvFldSz = sizeof(int);
        if (fOverWrite)
            memcpy(szToBuf, &inFldVal, inConvFldSz);
        break;

    case FLD_LONG :
        ulFldVal = atol(szFromBuf);
        inConvFldSz = sizeof(long);
        if (fOverWrite)
            memcpy(szToBuf, &ulFldVal, inConvFldSz);
        break;

    case FLD_CHAR :
        if (psrFldAttrList->inFieldSize < inFldSz)
            inConvFldSz = 0;         /* Field size exceeds expected size */
        else {
            inConvFldSz = psrFldAttrList->inFieldSize;
            memcpy(szTmpBuf, szFromBuf, inFldSz);
            szTmpBuf[inFldSz] = NULL_CH;

            if (inFldSz < inConvFldSz)
                pad((char *) szTmpBuf, (char *) szTmpBuf, 0, inConvFldSz, LEFT);

            if (fOverWrite)
                memcpy(szToBuf, szTmpBuf, inConvFldSz);
        }
        break;

    case FLD_STR :
        inConvFldSz = psrFldAttrList->inFieldSize + 1;
        memset(szTmpBuf, 0, sizeof(szTmpBuf));
        inFldSz = inConvertCase(szFromBuf, (char *) szTmpBuf);
        if (inFldSz < inConvFldSz) {
            if (fOverWrite)
                memcpy(szToBuf, szTmpBuf, inConvFldSz);
        } else {
            inConvFldSz = 0;         /* Field size exceeds expected size */
        }
        break;

    case FLD_BIT :
        if (psrFldAttrList->inFieldFullSize != inFldSz) {
            inConvFldSz = 0;         /* Field size is not expected size */
        } else {
            psrBitFldAttrList = psrFldAttrList;
            inFieldLoc = 15;
            memset(szTmpBuf, 0, 4 + 1);      /* Set 32 bits to zeroes */
            chBitCount = 0;
            chCurrBit = 0;
            chCurrByte = 0;

            while (szFromBuf[chBitCount]) {
                if (psrBitFldAttrList->fFieldZonTalks == 0) {
                    if (*(int *) szToBuf & (1 << inFieldLoc))
                        szTmpBuf[chCurrByte] |= pucMaskBits[chCurrBit];
                } else {
                    /** /pdebug((" Bit=%c",szFromBuf[chBitCount]));*/
                    if (szFromBuf[chBitCount] - '0')
                        szTmpBuf[chCurrByte] |= pucMaskBits[chCurrBit];
                }
                psrBitFldAttrList++;
                inFieldLoc--;

                if ((++chBitCount % 8) == 0)   /* One byte is over */ {
                    chCurrBit = 0;
                    chCurrByte++;
                } else
                    chCurrBit++;
            }

            inConvFldSz = sizeof(int);

            memcpy(szToBuf, szTmpBuf, inConvFldSz);
        }
        break;

    case 0x00 :
        /* More fields than required, in the record */
        inConvFldSz = -1;       /* Flag indicating the error */
        break;
    }

    if (inConvFldSz == 0)        /* InValid field length */ {
        strcpy(szDispMsg, szVarName);

        strcpy(szBuf, " Fld ");

        strcat(szDispMsg, szBuf);
        int2str(&szDispMsg[strlen(szDispMsg)], inFldIdx);
        vdDisplayAt(obDisp.inHomeCol, obDisp.inInputLine, szDispMsg, CLR_EOL);
        vdDisplayMessageFromFile(INVALID_LEN_ERR_MSG, ERROR_MSG);
        /** /pdebug (("FldSz=%d/%d",inFldSz,
        (psrFldAttrList->ucFieldType != FLD_BIT ? psrFldAttrList->inFieldSize:psrFldAttrList->inFieldFullSize)));
        */
    } else if (inConvFldSz == -1)        /* More fields than required */ {
        inConvFldSz = 0;
        strcpy(szDispMsg, szVarName);
        szDispMsg[5] = '\0';

        strcpy(szBuf, " Table, Field ");

        strcat(szDispMsg, szBuf);
        int2str(&szDispMsg[strlen(szDispMsg)], inFldIdx);
        vdDisplayAt(obDisp.inHomeCol, obDisp.inInputLine, szDispMsg, CLR_EOL);
        vdDisplayMessageFromFile(MORE_FLDS_ERR_MSG, ERROR_MSG);
    }

    return(inConvFldSz);
}

/*********************************************************************************************
* @func int | inExtractFlds |
*       Extract fields from the config.sys data string
*
* @parm FieldDefinition * | psrFldAttrList |
*       Field Definition
*
* @parm char * | szVarName |
*       Variable Name
*
* @parm unsigned char * | szInputBuffer |
*       Converted value
*
* @parm char * | szOutputBuffer |
*       Original string value
*
* @parm VB_BOOL | fNewFile |
*       Flag to idnetify new data file
*
* @rdesc return values.
* @flag int    |  Converted Field size
* @end
**********************************************************************************************/

int inExtractFlds(FieldDefinition* psrFldAttrList,char* szVarName,unsigned char* szInputBuffer,char* szOutputBuffer,VS_BOOL fNewFile) {
    int inFldIdx = 0,
    inFldSz = 0,
    inExtrSz = 0,
    inRecSz = 0,
    inSubRecNum = 1,
    inResult = 0,
    inBitFldCnt;
    char szTempBuffer[MAX_FIELD_SIZE + 1];
    char szMoreVarsName[MAX_CONFIG_NM_SIZE + 2];

    /** /pdebug(("--inExtractFlds--"));*/

    inFldIdx = 1;      /* Start from the first field */
    strcpy(szMoreVarsName, szVarName);
    while (inFldSz >= 0) {
        memset((char *) szTempBuffer, 0, sizeof(szTempBuffer));
        if ((inFldSz = fieldvar((char *) szInputBuffer, inFldIdx, ':', szTempBuffer)) >= 0) {
            /* correct for fields starting on even word boundaries */
            if (inRecSz % 2 == 1 && (psrFldAttrList->ucFieldType == FLD_INT || psrFldAttrList->ucFieldType == FLD_SHORT || psrFldAttrList->ucFieldType == FLD_LONG || psrFldAttrList->ucFieldType == FLD_BIT))
                inRecSz++;

            if ((inExtrSz = inConvFlds(szMoreVarsName, &szOutputBuffer[inRecSz], szTempBuffer, psrFldAttrList, inFldIdx, inFldSz, fNewFile)) == 0)
                return(VS_FALSE);
            inRecSz += inExtrSz;
            inFldIdx++;

            if (inResult) {
                put_env(szMoreVarsName, "", 0);
                inResult = 0;
            }

            if (psrFldAttrList->ucFieldType == FLD_BIT) {
                inBitFldCnt = psrFldAttrList->inFieldFullSize;
                psrFldAttrList += inBitFldCnt; /* past bit flds to next field */
            } else
                psrFldAttrList++;
        } else  /* Check for another pararmeter with data for the same record,
                         end of data fields or incomplete record */ {
            if (psrFldAttrList->ucFieldType != FLD_NULL) {
                memset(szMoreVarsName, 0, sizeof(szMoreVarsName));
                sprintf(szMoreVarsName, "%s%d", szVarName, inSubRecNum);
                memset(szInputBuffer, 0, MAX_ASSIST_CHUNK_SIZE + 1);
                if ((inResult = get_env(szMoreVarsName, (char *) szInputBuffer, MAX_ASSIST_CHUNK_SIZE)) > 0) {
                    /** /pdebug(("Found More->%s",szMoreVarsName));*/
                    inFldSz = 0;   /* to stay in while loop */
                    inFldIdx = 1;  /* beginning of new parameter */
                    inSubRecNum++;
                } else {
                    vdDisplayMessageFromFile(INVALID_TERMINATION_ERR_MSG, ERROR_MSG);
                    /** /pdebug(("Not Found->%s",szMoreVarsName));*/
                    return(VS_FALSE);
                }
            }
        }
    } /* end while */

    return(inRecSz);
}

/*********************************************************************************************
* @func VB_BOOL | fGetConfigRecs |
*       Updates the configuration records, the SPA messages and the menus
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       parameter description
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fGetConfigRecs(TRANSACTION_OBJECT* pobTran) {
    int inFileNum;
    int inMerchNum,
    inTotMerch;
    char szFileName[FILENAME_SIZE + 1];
    char szMerchNum[3];
    int inHostFileSize[10];

    /**/pdebug(("--fGetConfigRecs--"));/**/

    inFileNum = 0;

    if (fGetHostConfigSizes(inHostFileSize) != VS_TRUE) {
        vdSGErrorMessage(HFT_ERR_MSG);
        return(VS_FALSE);
    }

    /* Until all files updated */
    while (aszParamNames[inFileNum][0]) {
        if (fLoadConfigRecs(aszParamNames[inFileNum], ainRecordSizes[inFileNum], aszParamNames[inFileNum]) != VS_TRUE)
            return(VS_FALSE);
        inFileNum++;
    }

    inTotMerch = inGetMITTotRecs();
    for (inMerchNum = 1; inMerchNum <= inTotMerch; inMerchNum++) {
        int2str(szMerchNum, inMerchNum);
        pad(szMerchNum, szMerchNum, '0', 2, RIGHT);
        sprintf(szFileName, "M%s", szMerchNum);
        if (fLoadConfigRecs(szFileName, SIZE_MHT_REC, "MHT") != VS_TRUE)
            return(VS_FALSE);

        sprintf(szFileName, "C%s", szMerchNum);
        if (fLoadConfigRecs(szFileName, SIZE_CDT_REC, "CDT") != VS_TRUE)
            return(VS_FALSE);

        sprintf(szFileName, "S%s", szMerchNum);
        if (fLoadConfigRecs(szFileName, SIZE_CST_REC, "CST") != VS_TRUE)
            return(VS_FALSE);
    }

    if (fGetHostConfigRecs(inHostFileSize) != VS_TRUE) {
        vdSGErrorMessage(HFT_ERR_MSG);
        return(VS_FALSE);
    }

    if (fUpdateTRTRecs(pobTran) != VS_TRUE) {
        vdSGErrorMessage(TRT_ERR_MSG);
        return(VS_FALSE);
    }

    if (fUpdateSPAMessages(pobTran) != VS_TRUE) {
        vdSGErrorMessage(SPA_ERR_MSG21);
        return(VS_FALSE);
    }

    if (fUpdateMenus(pobTran) != VS_TRUE) {
        vdSGErrorMessage(MENUS_ERR_MSG21);
        return(VS_FALSE);
    }

    fResetZtConfigFlag();

    return(VS_TRUE);
} /* End of fGetConfigRecs () */

/*********************************************************************************************
* @func int | inSwapBytes |
*       Swap bytes
*
* @parm unsigned char * | *pucByte1 |
*
* @parm unsigned char * | *pucByte2 |
*
* @rdesc return values.
* @flag int    |  1
* @end
**********************************************************************************************/

int inSwapBytes(unsigned char* pucByte1,unsigned char* pucByte2) {
    unsigned char ucTmpByte = 0;

    ucTmpByte = *pucByte1;
    *pucByte1 = *pucByte2;
    *pucByte2 = ucTmpByte;

    return(1);
}
/*********************************************************************************************
* @func VB_BOOL | fGetHostConfigRecs |
*      Gets configuration records for the Host tables from
*      config.sys file, extracts the fields, and updates the
*      data file.
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fGetHostConfigRecs(int* pinHostFileSize) {
    char szConfigName[MAX_CONFIG_NM_SIZE + 1];
    char szDataFile[FILENAME_SIZE + 1] ;

    int inRecSize = 0;
    int inHostCounter;

    /**/pdebug(("--fGetHostConfigRecs--"));/**/
    inHostCounter = -1;
    while (++inHostCounter != MAX_HOSTS) {
        if (inLoadHDTRec(inHostCounter) != VS_SUCCESS) {
            vdDisplayMessageFromFile(HDT_ERR_MSG21, ERROR_MSG);
        	return(VS_FALSE);
        }
        strcpy(szConfigName, szGetHostFileName());
        sprintf(szDataFile, "%s.DAT", szConfigName);

        /* Host Format Tables no longer have just one record */
        inRecSize = *pinHostFileSize;
        if (fLoadConfigRecs(szConfigName, inRecSize, szConfigName) != VS_TRUE)
            return(VS_FALSE);
        pinHostFileSize++;
    }
    return (VS_TRUE);
} /* End of inGetHostConfigRecs () */

/*********************************************************************************************
* @func VB_BOOL | fGetHostConfigSizes |
*      Gets configuration record sizes for the Host tables from
*      config.sys file, extracts the fields, and updates the
*      data file.
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fGetHostConfigSizes(int* pinHostFileSize) {
    char szConfigName[MAX_CONFIG_NM_SIZE + 1];
    char szDataFile[FILENAME_SIZE + 1] ;

    int inRecSize = 0;
    int inHostCounter;

    /**/pdebug(("--fGetHostConfigRecs--"));/**/
    inHostCounter = -1;
    while (++inHostCounter != MAX_HOSTS) {
        if (inLoadHDTRec(inHostCounter) != VS_SUCCESS) {
            vdDisplayMessageFromFile(HDT_ERR_MSG21, ERROR_MSG);
        	return(VS_FALSE);
        }
        strcpy(szConfigName, szGetHostFileName());
        sprintf(szDataFile, "%s.DAT", szConfigName);

        /* Host Format Tables no longer have just one record */
        *pinHostFileSize = ((int) lnGetFileSize(szDataFile) - GEN_VER_SIZE) / inGetMITTotRecs() ;
        pinHostFileSize++;
    }
    return (VS_TRUE);
} /* End of inGetHostConfigSizes () */


/*********************************************************************************************
* @func VB_BOOL | fLoadConfigRecs |
*      Updates the data file with fields from config.sys
*
* @parm char * | pszConfigName |
*           Data file name
*
* @parm int | inConfigRecSize |
*           Data file Record Size
*
* @rdesc return values.
* @flag VB_BOOL |  TRUE or FALSE
* @end
**********************************************************************************************/

VS_BOOL fLoadConfigRecs(char* pszConfigName,int inConfigRecSize,char* pszFldDefName) {
    unsigned char szConfigBuffer[256];
    char szConfigName[MAX_CONFIG_NM_SIZE + 1];
    char szDataBuffer[MAX_CONFIG_REC_SIZE],
    szDataFile[FILENAME_SIZE + 1] ;
    char szFileName[FILENAME_SIZE + 1];
    char szTempFile[FILENAME_SIZE + 1];
    int hDataFile,
    hFieldDescriptionFile;
    int inRecNum,
    inNumRecs = 0,
    inResult;
    char szRecNum[3];

    long lnDescriptionSize;

    VS_BOOL fNewFile = VS_FALSE;
    VS_BOOL fExtractAny;
    VS_BOOL fMoreVars = VS_FALSE;
    FieldDefinition* psrFldAttrList = NULL;
    FieldDefinition* psrStart = NULL;
    long lTemp;

    /**/pdebug(("--fLoadConfigRecs--"));/**/

    vdGetMessageFromFile(TEMP_CONFIG_FN_MSG, szTempFile);

    /* Initialize record number for the data file */
    inRecNum = 1;
    hDataFile = -1;
    fMoreVars = VS_TRUE;
    fExtractAny = VS_FALSE;

    /* Get Field Definition File */
    sprintf(szFileName, "F:%s.FLD", pszFldDefName);
    if ((hFieldDescriptionFile = open(szFileName, O_RDONLY)) != -1) {
        if ((lnDescriptionSize = lseek(hFieldDescriptionFile, 0L, SEEK_END) - GEN_VER_SIZE) <= 0L) {
            close(hFieldDescriptionFile);
            vdSGErrorMessage(MENU_SIZE_ERR_MSG);
            return (VS_FALSE);
        }

        if ((psrFldAttrList = (FieldDefinition *) pchAlloc((unsigned) lnDescriptionSize)) == NULL_CH) {
            close(hFieldDescriptionFile);
            vdSGErrorMessage(MENU_SEEK_ERR_MSG);
            return(VS_FALSE);
        }

        /* Go to the top of the file and copy the file header */
        lseek(hFieldDescriptionFile, 0L, SEEK_SET);
        if (read(hFieldDescriptionFile, szDataBuffer, GEN_VER_SIZE) != GEN_VER_SIZE) {
            close(hFieldDescriptionFile);
            vdSGErrorMessage(BAD_READ_MSG21);
            vdFree((char *) psrFldAttrList);
            return(VS_FALSE);
        }

        if (read(hFieldDescriptionFile, (char *) psrFldAttrList, (int) lnDescriptionSize) != lnDescriptionSize) {
            close(hFieldDescriptionFile);
            vdSGErrorMessage(MENU_READ_ERR_MSG);
            vdFree((char *) psrFldAttrList);
            return(VS_FALSE);
        }
        psrStart = psrFldAttrList;
        close(hFieldDescriptionFile);
    }

    /* Search for all records for a given file */
    while (fMoreVars) {
        /*
         * Create parameter name, e.g, "CDT01", "HDT02" etc.
         */
        psrFldAttrList = psrStart;
        int2str(szRecNum, inRecNum);
        pad(szRecNum, szRecNum, '0', 2, RIGHT);
        sprintf(szConfigName, "%s%s", pszConfigName, szRecNum);
        /**/pdebug((szConfigName));/**/

        /* No records */
        memset(szConfigBuffer, 0, sizeof(szConfigBuffer));
        if ((inResult = get_env(szConfigName, (char *) szConfigBuffer, sizeof(szConfigBuffer))) <= 0)
            fMoreVars = VS_FALSE;
        else {
            /* Found Config Variable for file */
            fExtractAny = VS_TRUE;
            /* First record, create the file */
            if (inRecNum == 1) {
                sprintf(szDataFile, "%s.DAT", pszConfigName);
                fNewFile = VS_TRUE;
                inNumRecs = 0;
                if ((hDataFile = open(szDataFile, O_RDWR | O_CREAT | O_EXCL)) < 0) {
                    if (errno == EEXIST) {
                        fNewFile = VS_FALSE;
                        hDataFile = open(szDataFile, O_RDWR);
                        lTemp = lseek(hDataFile, 0L, SEEK_END);
                        inNumRecs = (int) ((lTemp - GEN_VER_SIZE) / (long) inConfigRecSize);
                        /**/pdebug(("%s Exists w/ %d recs.", szDataFile, inNumRecs));/**/
                        close(hDataFile);
                    } else {
                        /**/pdebug(("No existing file=%d", errno));/**/
                        vdSGErrorMessage(FILE_OPEN_ERR_MSG);
                        return(VS_FALSE);
                    }
                } else
                    close(hDataFile);
                /* Create temp new file, write file header */
                if ((hDataFile = open(szTempFile, O_RDWR | O_CREAT)) > 0) {
                    if (write(hDataFile, szDataBuffer, GEN_VER_SIZE) != GEN_VER_SIZE) {
                        /**/pdebug(("File Write Error"));/**/
                        vdSGErrorMessage(TABLES_ERR_MSG);
                        vdFree((char *) psrFldAttrList);
                        close(hDataFile);
                        return(VS_FALSE);
                    }
                    close(hDataFile);
                } else {
                    /**/pdebug(("%s file Fail=%d,%d", szTempFile, hDataFile, errno));/**/
                    vdFree((char *) psrFldAttrList);
                    vdSGErrorMessage(FILE_OPEN_ERR_MSG);
                    return(VS_FALSE);
                }
            }
            /* Adding more recs than we started with */
            else if (inRecNum > inNumRecs)
                fNewFile = VS_TRUE;

            if (fNewFile == VS_FALSE) {
                if (inLoadConfRec(szDataFile, inConfigRecSize, inRecNum - 1, szDataBuffer) != VS_SUCCESS) {
                    vdSGErrorMessage(TABLES_ERR_MSG);
                    vdFree((char *) psrFldAttrList);
                    return(VS_FALSE);
                }
            }

            /* Extract and format the data */
            if ((inExtractFlds(psrFldAttrList, szConfigName, szConfigBuffer, szDataBuffer, fNewFile)) == VS_FALSE) {
                vdSGErrorMessage(TABLES_ERR_MSG);
                vdFree((char *) psrFldAttrList);
                return(VS_FALSE);
            }

            if (inSaveConfRec(szTempFile, inConfigRecSize, inRecNum - 1, szDataBuffer) != VS_SUCCESS) {
                vdSGErrorMessage(TABLES_ERR_MSG);
                vdFree((char *) psrFldAttrList);
                return(VS_FALSE);
            }
            put_env(szConfigName, "", 0); /* Delete the config var */
        }

        inRecNum++;
    }

    /* Replace existing data file with new data file if
     * Config variables found for file
     */
    if (fExtractAny == VS_TRUE) {
        /* Delete Old Data File */
        if (inRemoveFile((char *) szDataFile)) {
            vdSGErrorMessage(FILE_REMOVE_ERR_MSG);
            vdFree((char *) psrFldAttrList);
            return(VS_FALSE);
        }

        /* Rename temp file to data file */
        if (rename(szTempFile, szDataFile)) {
            vdSGErrorMessage(FILE_RENAME_ERR_MSG);
            /**/pdebug(("(%d) From %s to %s.", errno, szTempFile, szDataFile)); /**/
            vdFree((char *) psrFldAttrList);
            return(VS_FALSE);
        }
    }

    vdFree((char *) psrFldAttrList);
    return(VS_TRUE);
}

int inInitConfigRecs(TRANSACTION_OBJECT* pobTran) {
    if (fZtConfigReqd() == VS_TRUE) {
        vdDisplayMessageFromFile(ZT_LOAD_MSG, STATUS_MSG);
        if (fGetConfigRecs(pobTran) != VS_TRUE) {
            vdSGErrorMessage(lnGGErrorMessage());
            return(VS_ERROR);
        }
    }

    if (inLoadTCTRec(0) != VS_SUCCESS) {
        vdSGErrorMessage(TCT_ERR_MSG21);
        return (VS_ERR);
    }

    if (inGetDefaultLCT() != VS_SUCCESS) {
        vdSGErrorMessage(LCT_ERR_MSG);
        return (VS_ERR);
    }

    return (VS_SUCCESS);
}

/*-------------------------------------------------------------------------
    Function :    fUpdateTRTRecs
    Description :
    Parameters :
    Returns :
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   08/21/97 Pat_G1     Added fOverage flag.
--------------------------------------------------------------------------*/


VS_BOOL fUpdateTRTRecs(TRANSACTION_OBJECT* pobTran) {
    VS_BOOL fMoreVars;
    int inRecNum,
    inHostNum,
    inTRTRecNum = 0,
    inFldSz,
    inFldIdx,
    inNoHDTRecs;
    short shFldVal = 0;
    char szNULLStr[1 + 1];
    char szConfigName[CONFIG_NM_SIZE + 1],
    szTempBuffer[DATA_SIZE + 1];
    unsigned char szConfigBuffer[MAX_ASSIST_CHUNK_SIZE + 1];

    /** /pdebug (("--inUpdateTRTRecs--"));*/


    /*
     *      Check for TRT for each host.
     */

    inNoHDTRecs = inGetHDTTotRecs();
    for (inHostNum = 0; inHostNum < inNoHDTRecs; ++inHostNum) {
        /* Load the HDT to get the TRT filename */
        if (inLoadHDTRec(inHostNum) != VS_SUCCESS) {
            vdSGErrorMessage(HDT_ERR_MSG21);
            return(VS_FALSE);
        }
        inFldSz = 1;
        inFldIdx = 1;
        inRecNum = 1;
        fMoreVars = VS_TRUE;
        while (fMoreVars)      /* Search for all TRT records */ {
            sprintf(szConfigName, "T%02d%02d", inHostNum, inRecNum);
            memset(szConfigBuffer, 0, sizeof(szConfigBuffer));
            if (get_env(szConfigName, (char *) szConfigBuffer, sizeof(szConfigBuffer)) <= 0)   /* No records */
                fMoreVars = VS_FALSE;
            else {
                /** /pdebug (("Got %s",szConfigName));*/
                while (inFldSz > 0) {
                    if ((inFldSz = fieldvar((char *) szConfigBuffer, inFldIdx, ':', szTempBuffer)) > 0) {
                        // char TranAbbrev[TRT_ABBREV_SIZE + 1];  /* Field 4      */
                        if (inFldIdx != 4)
                            shFldVal = (short) atoi(szTempBuffer);
                        /** /pdebug (("Fld = %d,",inFldIdx));*/
                        /** /pdebug (("Data = %s",szTempBuffer));*/
                        switch (inFldIdx) {
                        case 1:
                            if ((inTRTRecNum = inLoadTRTRec(pobTran, shFldVal)) == VS_ERR) {
                                /** /pdebug (("Fld %d = %d",inFldIdx,shFldVal));*/
                                vdSGErrorMessage(TRT_ERR_MSG);
                                return(VS_FALSE);
                            }
                            //if (pobTran->srTRTRec.inTransactionCode != shFldVal)
                            if (shGetTransactionCode(pobTran) != shFldVal) {
                                vdSGErrorMessage(INVALID_TRANS_ERR_MSG);
                                return(VS_FALSE);
                            }
                            break;

                        case 2:
                            //pobTran->srTRTRec.inTranType = shFldVal;
                            vdSetTranType(pobTran, shFldVal);
                            break;

                        case 3:
                            //pobTran->srTRTRec.inCardMode = shFldVal;
                            vdSetCardMode(pobTran, shFldVal);
                            break;

                        case 4:
                            //strcpy (pobTran->srTRTRec.szTranAbbrev, szTempBuffer);
                            vdSetTranAbbrev(pobTran, szTempBuffer);
                            break;

                        case 5:
                            //pobTran->srTRTRec.uiBannedCardTypes = shFldVal;
                            vdSetBannedCardTypes(pobTran, shFldVal);
                            break;

                        case 6:
                            //pobTran->srTRTRec.inTipProc = shFldVal;
                            vdSetTipProc(pobTran, shFldVal);
                            break;

                        case 7:
                            //pobTran->srTRTRec.fDataCapture = shFldVal;
                            vdSetDataCapture(pobTran, shFldVal);
                            break;

                        case 8:
                            //pobTran->srTRTRec.fOverage = shFldVal;
                            vdSetOverage(pobTran, shFldVal);
                            break;

                        case 9:
                            //pobTran->srTRTRec.fReversal = shFldVal;
                            vdSetReversal(pobTran, shFldVal);
                            break;

                        case 10:
                            //pobTran->srTRTRec.fCheckFloorLimit = shFldVal;
                            vdSetCheckFloorLimit(pobTran, shFldVal);
                            break;

                        case 11:
                            //pobTran->srTRTRec.fNotUsed1 = shFldVal;
                            vdSetNotUsed1(pobTran, shFldVal);
                            break;

                        case 12:
                            //pobTran->srTRTRec.fAllowed = shFldVal;
                            vdSetAllowed(pobTran, shFldVal);
                            break;

                        case 13:
                            //pobTran->srTRTRec.fAdjustAllowed = shFldVal;
                            vdSetAdjustAllowed(pobTran, shFldVal);
                            break;

                        case 14:
                            //pobTran->srTRTRec.fVoidAllowed = shFldVal;
                            vdSetVoidAllowed(pobTran, shFldVal);
                            break;

                        case 15:
                            //pobTran->srTRTRec.fPrintReceipt = shFldVal;
                            vdSetPrintReceipt(pobTran, shFldVal);
                            break;

                        case 16:
                            //pobTran->srTRTRec.fAdjustReceipt = shFldVal;
                            vdSetAdjustReceipt(pobTran, shFldVal);
                            break;

                        case 17:
                            //pobTran->srTRTRec.fVoidReceipt = shFldVal;
                            vdSetVoidReceipt(pobTran, shFldVal);
                            break;

                        case 18:
                            //pobTran->srTRTRec.fOffline = shFldVal;
                            vdSetOffline(pobTran, shFldVal);
                            break;

                        case 19:
                            //pobTran->srTRTRec.fAdjustOffline = shFldVal;
                            vdSetAdjustOffline(pobTran, shFldVal);
                            break;

                        case 20:
                            //pobTran->srTRTRec.fVoidOffline = shFldVal;
                            vdSetVoidOffline(pobTran, shFldVal);
                            break;

                        case 21:
                            //pobTran->srTRTRec.fIncInvNum = shFldVal;
                            vdSetIncInvNum(pobTran, shFldVal);
                            break;

                        case 22:
                            //pobTran->srTRTRec.fAdjustIncInvNum = shFldVal;
                            vdSetAdjustIncInvNum(pobTran, shFldVal);
                            break;

                        case 23:
                        case 24:
                        case 25:
                        case 26:
                        case 27:
                        case 28:
                        case 29:
                        case 30:
                            break;

                        case 31:
                            //pobTran->srTRTRec.fVoidIncInvNum = shFldVal;
                            vdSetVoidIncInvNum(pobTran, shFldVal);
                            break;

                        case 32:
                            vdSetIncHostInvNum(pobTran, shFldVal);
                            break;

                        case 33:
                            vdSetAdjustIncHostInvNum(pobTran, shFldVal);
                            break;

                        case 34:
                            vdSetVoidIncHostInvNum(pobTran, shFldVal);
                            break;

                        case 35:
                            vdSetRetryPrompt(pobTran, shFldVal);
                            break;

                        case 36:
                            //pobTran->srTRTRec.fNotUsed4 = shFldVal;
                            vdSetNotUsed4(pobTran, shFldVal);
                            break;

                        case 37:
                            //pobTran->srTRTRec.fNotUsed3 = shFldVal;
                            vdSetNotUsed3(pobTran, shFldVal);
                            break;

                        case 38:
                            //pobTran->srTRTRec.fNotUsed2 = shFldVal;
                            vdSetNotUsed2(pobTran, shFldVal);
                            break;
                        }
                    } else {
                        if (inFldIdx != 39) {
                            vdSGErrorMessage(INVALID_TERMINATION_ERR_MSG);
                            return(VS_FALSE);
                        }
                    }
                    inFldIdx++;
                }

                inSaveTRTRec(pobTran, inTRTRecNum);
                inRecNum++;
                inFldIdx = 1;
                inFldSz = 1;
                memset(szNULLStr, '\0', sizeof(szNULLStr));
                put_env(szConfigName, szNULLStr, 0); /* Delete the config var */
            } /*End Else More Recs */
        } /* End While MoreVars */
    } /* End For HostNums */

    return(VS_TRUE);
} /* End of fUpdateTRTRecs() */


#undef VSZTCONF_C

